package com.boomkeeper.archive.file;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import com.boomkeeper.archive.filter.FileNameFilter;
import com.boomkeeper.archive.model.ArchiveDirctory;
import com.boomkeeper.core.config.BaseConfig;
import com.boomkeeper.core.model.ChangeOrderData;
import com.boomkeeper.core.utils.ArchiveUtils;
import com.google.common.io.Files;

@Component("archive")
public class Archive {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(Archive.class);
	
	@Autowired
	private BaseConfig baseConfig;
	
	@Autowired
	private Extract extract;
	
	@Autowired
	private ArchiveDirctory archiveDirctory;
	
	private FileFilter excelFilesFilter = new SuffixFileFilter(new String[]{"xls", "xlsx"}, IOCase.INSENSITIVE);
	private FileFilter propertiesFilesFilter = new SuffixFileFilter("properties", IOCase.INSENSITIVE);
	private FileFilter sqlFilesFilter = new SuffixFileFilter("sql", IOCase.INSENSITIVE);
	private FileFilter xmlFilesFilter = new SuffixFileFilter("xml", IOCase.INSENSITIVE);
	private FileFilter warFilesFilter = new SuffixFileFilter("war", IOCase.INSENSITIVE);

	private FileFilter schemeFilesFilter = new FileNameFilter("LTE-Scheme");
	private FileFilter testReportFilesFilter = new FileNameFilter("LTE-TestReport");
	
	public Archive mkdirs() {
		File changeOrderFile = new File(this.archiveDirctory.getLteVersionChangeOrderPath());
		File schemefile = new File(this.archiveDirctory.getLteVersionSchemePath());
		File testReportFile = new File(this.archiveDirctory.getLteVersionTestReportPath());
		
		if (changeOrderFile.exists() || schemefile.exists() || testReportFile.exists()) {
			LOGGER.error("以下目录已经存在：\n{} \n{} \n{}", this.archiveDirctory.getLteVersionChangeOrderPath(),
					this.archiveDirctory.getLteVersionSchemePath(), this.archiveDirctory.getLteVersionTestReportPath());
			LOGGER.error("归档的根目录必须为空：\n{}", baseConfig.getLteVersion().getLteVersionPath());
			System.exit(0);
		} else {
			changeOrderFile.mkdirs();
			schemefile.mkdir();
			testReportFile.mkdir();
		}
		
		return this;
	}
	
	public Archive moveFiles() {
		File allChangeOrderFiles = new File(baseConfig.getLteVersion().getLteZipPath());
		
		File[] excelFiles = allChangeOrderFiles.listFiles(this.excelFilesFilter);
		File[] schemeFiles = allChangeOrderFiles.listFiles(this.schemeFilesFilter);
		File[] testReportFiles = allChangeOrderFiles.listFiles(this.testReportFilesFilter);
		File[] propertiesFiles = allChangeOrderFiles.listFiles(this.propertiesFilesFilter);
		File[] sqlFiles = allChangeOrderFiles.listFiles(this.sqlFilesFilter);
		File[] xmlFiles = allChangeOrderFiles.listFiles(this.xmlFilesFilter);
		
		try {
			for (File file : excelFiles) {
				Files.copy(file, new File(archiveDirctory.getLteVersionChangeOrderPath() + file.getName()));
			}
			for (File file : schemeFiles) {
				Files.copy(file, new File(archiveDirctory.getLteVersionSchemePath() + file.getName()));
			}
			for (File file : testReportFiles) {
				Files.copy(file, new File(archiveDirctory.getLteVersionTestReportPath() + file.getName()));
			}
			for (File file : propertiesFiles) {
				Files.copy(file, new File(archiveDirctory.getLteVersionPath() + file.getName()));
			}
			for (File file : sqlFiles) {
				Files.copy(file, new File(archiveDirctory.getLteVersionPath() + file.getName()));
			}
			for (File file : xmlFiles) {
				Files.copy(file, new File(archiveDirctory.getLteVersionPath() + file.getName()));
			}
		} catch (IOException e) {
			LOGGER.error("复制文件到归档目录时发生异常", e);
		}
		
		this.copyExcelFile();
		
		return this;
	}
	
	public Archive extracFiles() {
		extract.unZipFiles();
		return this;
	}
	
	/**
	 * call this methed after completion of all tasks
	 * @return 
	 */
	public Archive deleteFiles() {
		this.deleteFiles(baseConfig.getLteVersion().getLteZipPath());
		this.deleteFiles(baseConfig.getLteVersion().getLteVersionPath());
		return this;
	}
	
	public void deleteFiles(String delFile) {
		try {
			FileUtils.deleteDirectory(new File(delFile));
		} catch (IOException e) {
			LOGGER.error("删除目录异常", e);
		}
	}
	
	/**从项目中copy Excel模板文件到版本路径下*/
	public void copyExcelFile() {
		try {
			File excelFile = ResourceUtils.getFile("classpath:LTE-Portal-Version.xlsx");
			File destExcelFile = new File(archiveDirctory.getLteVersionPath() + excelFile.getName());
			Files.copy(excelFile, destExcelFile);
		} catch (IOException e) {
			LOGGER.error("复制模板LTE-Portal-Version.xlsx异常", e);
		}
	}
	
	/**
	 * 整理变更单
	 * @return
	 */
	public Archive collectChangeOrderFiles() {
		this.mkdirs().extracFiles().moveFiles();
		return this;
	}
	
	/**
	 * 归档统计
	 * @param changeOrderData
	 * @return
	 */
	public Archive collectStatistics(ChangeOrderData changeOrderData) {
		this.copyWar();
		
		List<String> list = changeOrderData.getPublishInstructionList();
		File file = new File(this.archiveDirctory.getLteVersionPath());
		File[] propertiesFiles = file.listFiles(this.propertiesFilesFilter);
		File[] sqlFiles = file.listFiles(this.sqlFilesFilter);
		File[] xmlFiles = file.listFiles(this.xmlFilesFilter);
		File[] warFiles = file.listFiles(this.warFilesFilter);
		
		for (File warFile : warFiles) {
			list.add("停止门户" + warFile.getName() + "应用");
		}
		for (File configFile : propertiesFiles) {
			list.add("根据" + configFile.getName() + "修改门户配置文件/portal/portal.properties");
		}
		for (File configFile : sqlFiles) {
			list.add("根据" + configFile.getName() + "执行脚本");
		}
		for (File configFile : xmlFiles) {
			list.add("根据" + configFile.getName() + "修改门户配置文件/portal/MDA.xml");
		}
		for (File warFile : warFiles) {
			list.add("根据版本路径安装新的" + warFile.getName() + "应用，并设置上下根为" + ArchiveUtils.getContextRootName(warFile));
		}
		
		return this;
	}
	
	/**copy war包到版本路径下*/
	public void copyWar() {
		try {
			File srcWarFile = new File(this.baseConfig.getLteVersion().getLteWarPath());
			File[] warFiles = srcWarFile.listFiles(this.warFilesFilter);
			for (File srcfile : warFiles) {
				File destWarFile = new File(archiveDirctory.getLteVersionPath() + srcfile.getName());
				Files.copy(srcfile, destWarFile);
			}
		} catch (IOException e) {
			LOGGER.error("复制war到版本路径下异常", e);
		}
	}
}